update due to information from BablFishStats
authorØyvind Kolås <ok@src.gnome.org>
Mon, 26 Sep 2005 22:09:07 +0000 (22:09 +0000)
committerØyvind Kolås <ok@src.gnome.org>
Mon, 26 Sep 2005 22:09:07 +0000 (22:09 +0000)
ChangeLog
babl/base/model-gray.c
babl/base/model-rgb.c
babl/base/model-ycbcr.c
docs/index-static.html.in
extensions/gggl.c

index 8385846bd1e690826725239956eeadff5ab48ce2..4bc74d304b1a56cf45a0e05980dbe5204ccd9119 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2005-09-27  Øyvind Kolås  <pippin@gimp.org>
+
+       Updates done due to improvements gotten from BablFishStat feedback.
+
+       * babl/base/model-gray.c: (components), (models),
+       (rgba2gray_gamma_2_2_premultiplied),
+       (gray_gamma_2_2_premultiplied2rgba), (conversions):
+       * babl/base/model-rgb.c: (components), (models), (copy_strip_1),
+       (g3_gamma_2_2), (g3_inv_gamma_2_2),
+       (non_premultiplied_to_premultiplied),
+       (premultiplied_to_non_premultiplied),
+       (rgba2rgba_gamma_2_2_premultiplied),
+       (rgba_gamma_2_2_premultiplied2rgba), (rgba2rgba_gamma_2_2),
+       (rgba_gamma_2_22rgba), (conversions), (formats):
+       * babl/base/model-ycbcr.c: (models), (formats):
+       * docs/index-static.html.in:
+       * extensions/gggl.c: (conv_F_8), (conv_8_F), (conv_F_D),
+       (conv_D_F), (conv_rgba8_rgbaF), (conv_rgb8_rgbF), (conv_ga8_gaF),
+       (conv_rgbaF_rgbaD), (conv_rgbaD_rgbaF), (conv_rgbAF_rgbaF),
+       (conv_rgbaF_rgbAF), (conv_rgbaF_rgbF), (conv_rgbF_rgbaF),
+       (conv_rgbaF_gaF), (conv_rgbaF_rgb8), (conv_rgbA16_rgbaF),
+       (conv_rgb8_rgba8), (conv_rgbA8_rgb8), (init):
+
 2005-09-27  Øyvind Kolås  <pippin@gimp.org>
 
        Upgrade of BablFishPath.
index 37044cfcde533a16bf668551cea07fdbf31f2d94..e96a0290d8756cd3b59dded464323cd1078a6f53 100644 (file)
@@ -53,7 +53,13 @@ components (void)
 
   babl_component_new (
    "Y'", 
-   "id",    BABL_LUMINANCE_GAMMA_2_2,
+   "id",    BABL_LUMA,
+   "luma",
+   NULL);
+
+  babl_component_new (
+   "Y'a", 
+   "id",    BABL_LUMA_MUL_ALPHA,
    "luma",
    NULL);
 }
@@ -66,26 +72,34 @@ models (void)
     babl_component_id (BABL_LUMINANCE),
     NULL);
 
+
   babl_model_new (
-    "id", BABL_GRAY_GAMMA_2_2,
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    "id", BABL_GRAY_ALPHA,
+    babl_component_id (BABL_LUMINANCE),
+    babl_component_id (BABL_ALPHA),
     NULL);
 
   babl_model_new (
-    "id", BABL_GRAY_GAMMA_2_2_ALPHA,
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    "id", BABL_GRAY_ALPHA_PREMULTIPLIED,
+    babl_component_id (BABL_LUMINANCE_MUL_ALPHA),
     babl_component_id (BABL_ALPHA),
     NULL);
 
+
   babl_model_new (
-    "id", BABL_GRAY_ALPHA,
-    babl_component_id (BABL_LUMINANCE),
+    "id", BABL_GRAY_GAMMA_2_2,
+    babl_component_id (BABL_LUMA),
+    NULL);
+
+  babl_model_new (
+    "id", BABL_GRAY_GAMMA_2_2_ALPHA,
+    babl_component_id (BABL_LUMA),
     babl_component_id (BABL_ALPHA),
     NULL);
 
   babl_model_new (
-    "id", BABL_GRAY_ALPHA_PREMULTIPLIED,
-    babl_component_id (BABL_LUMINANCE_MUL_ALPHA),
+    "id", BABL_GRAY_GAMMA_2_2_ALPHA_PREMULTIPLIED,
+    babl_component_id (BABL_LUMA_MUL_ALPHA),
     babl_component_id (BABL_ALPHA),
     NULL);
 }
@@ -412,6 +426,62 @@ premultiplied_to_non_premultiplied (int    src_bands,
   return n;
 }
 
+static long
+rgba2gray_gamma_2_2_premultiplied (void *src,
+                                   void *dst,
+                                   long  n)
+{
+  while (n--)
+    {
+      double red   = ((double*)src)[0];
+      double green = ((double*)src)[1];
+      double blue  = ((double*)src)[2];
+      double alpha = ((double*)src)[3];
+
+      double luminance;
+      double luma;
+        
+      luminance  = red   * RGB_LUMINANCE_RED +
+                   green * RGB_LUMINANCE_GREEN +
+                   blue  * RGB_LUMINANCE_BLUE;
+      luma = linear_to_gamma_2_2 (luminance);
+
+      ((double*)dst)[0] = luma * alpha;
+      ((double*)dst)[1] = alpha;
+
+      src+=4 * sizeof (double);
+      dst+=2 * sizeof (double);
+    }
+  return n;
+}
+
+
+static long
+gray_gamma_2_2_premultiplied2rgba (void *src,
+                                   void *dst,
+                                   long   n)
+{
+  while (n--)
+    {
+      double luma  = ((double*) src)[0];
+      double alpha = ((double*) src)[1];
+      double luminance;
+
+      luma = luma / alpha;
+      luminance = gamma_2_2_to_linear (luma);
+      
+      ((double*)dst)[0] = luminance;
+      ((double*)dst)[1] = luminance;
+      ((double*)dst)[2] = luminance;
+      ((double*)dst)[3] = alpha;
+
+      src+=2 * sizeof (double);
+      dst+=4 * sizeof (double);
+    }
+  return n;
+}
+
+
 static void
 conversions (void)
 {
@@ -443,6 +513,21 @@ conversions (void)
     NULL
   );
 
+
+  babl_conversion_new (
+    babl_model_id (BABL_GRAY_GAMMA_2_2_ALPHA_PREMULTIPLIED),
+    babl_model_id (BABL_RGBA),
+    "linear",      gray_gamma_2_2_premultiplied2rgba,
+    NULL
+  );
+
+  babl_conversion_new (
+    babl_model_id (BABL_RGBA),
+    babl_model_id (BABL_GRAY_GAMMA_2_2_ALPHA_PREMULTIPLIED),
+    "linear",      rgba2gray_gamma_2_2_premultiplied,
+    NULL
+  );
+
   babl_conversion_new (
     babl_model_id (BABL_GRAY),
     babl_model_id (BABL_RGBA),
index e64a86f194189438cda887086b5deee23bd9c20c..0cb7e3f7136203bdd9bc53807fb0d2e39c22ee1e 100644 (file)
@@ -40,6 +40,30 @@ static void
 components (void)
 {
 
+
+
+  babl_component_new (
+    "Ra",
+    "id",    BABL_RED_MUL_ALPHA,
+    "luma",
+    "chroma",
+    "alpha",
+    NULL);
+  babl_component_new (
+    "Ga",
+    "id",    BABL_GREEN_MUL_ALPHA,
+    "luma",
+    "chroma",
+    "alpha",
+    NULL);
+  babl_component_new (
+    "Ba",
+    "id",    BABL_BLUE_MUL_ALPHA,
+    "luma",
+    "chroma",
+    "alpha",
+    NULL);
+
   babl_component_new (
     "R'",
    "id",    BABL_RED_GAMMA_2_2,
@@ -61,29 +85,26 @@ components (void)
    "chroma",
    NULL);
 
-
   babl_component_new (
-    "Ra",
-    "id",    BABL_RED_MUL_ALPHA,
+    "R'a",
+   "id",    BABL_RED_GAMMA_2_2_MUL_ALPHA,
     "luma",
     "chroma",
-    "alpha",
     NULL);
+
   babl_component_new (
-    "Ga",
-    "id",    BABL_GREEN_MUL_ALPHA,
-    "luma",
-    "chroma",
-    "alpha",
-    NULL);
+    "G'a",
+   "id",    BABL_GREEN_GAMMA_2_2_MUL_ALPHA,
+   "luma", 
+   "chroma",
+   NULL);
+  
   babl_component_new (
-    "Ba",
-    "id",    BABL_BLUE_MUL_ALPHA,
-    "luma",
-    "chroma",
-    "alpha",
-    NULL);
-
+    "B'a",
+   "id",    BABL_BLUE_GAMMA_2_2_MUL_ALPHA,
+   "luma",
+   "chroma",
+   NULL);
 }
 
 static void
@@ -119,6 +140,14 @@ models (void)
     babl_component_id (BABL_BLUE_GAMMA_2_2),
     babl_component_id (BABL_ALPHA),
     NULL);
+
+  babl_model_new (
+    "id", BABL_RGBA_GAMMA_2_2_PREMULTIPLIED,
+    babl_component_id (BABL_RED_GAMMA_2_2_MUL_ALPHA),
+    babl_component_id (BABL_GREEN_GAMMA_2_2_MUL_ALPHA),
+    babl_component_id (BABL_BLUE_GAMMA_2_2_MUL_ALPHA),
+    babl_component_id (BABL_ALPHA),
+    NULL);
 }
 
 static long
@@ -128,8 +157,9 @@ copy_strip_1 (int    src_bands,
               int    dst_bands,
               void **dst,
               int   *dst_pitch,
-              long   n)
+              long   samples)
 {
+  long n=samples; 
   BABL_PLANAR_SANITY
   while (n--)
     {
@@ -147,7 +177,7 @@ copy_strip_1 (int    src_bands,
 
       BABL_PLANAR_STEP
     }
-  return n;
+  return samples;
 }
 
 static long
@@ -157,10 +187,10 @@ g3_gamma_2_2 (int    src_bands,
               int    dst_bands,
               void **dst,
               int   *dst_pitch,
-              long   n)
+              long   samples)
 {
+  long n=samples;
   BABL_PLANAR_SANITY
-
   while (n--)
     {
       int band;
@@ -171,7 +201,7 @@ g3_gamma_2_2 (int    src_bands,
 
       BABL_PLANAR_STEP
     }
-  return n;
+  return samples;
 }
 
 
@@ -182,10 +212,10 @@ g3_inv_gamma_2_2 (int    src_bands,
                   int    dst_bands,
                   void **dst,
                   int   *dst_pitch,
-                  long   n)
+                  long   samples)
 {
+  long n=samples;
   BABL_PLANAR_SANITY
-
   while (n--)
     {
       int band;
@@ -202,7 +232,7 @@ g3_inv_gamma_2_2 (int    src_bands,
         }
       BABL_PLANAR_STEP
     }
-  return n;
+  return samples;
 }
 
 static long
@@ -212,10 +242,10 @@ non_premultiplied_to_premultiplied (int    src_bands,
                                     int    dst_bands,
                                     void **dst,
                                     int   *dst_pitch,
-                                    long   n)
+                                    long   samples)
 {
+  long n=samples; 
   BABL_PLANAR_SANITY
-
   while (n--)
     {
       double alpha;
@@ -230,7 +260,7 @@ non_premultiplied_to_premultiplied (int    src_bands,
 
       BABL_PLANAR_STEP
     }
-  return n;
+  return samples;
 }
 
 static long
@@ -240,10 +270,10 @@ premultiplied_to_non_premultiplied (int    src_bands,
                                     int    dst_bands,
                                     void **dst,
                                     int   *dst_pitch,
-                                    long   n)
+                                    long   samples)
 {
+  long n=samples; 
   BABL_PLANAR_SANITY
-
   while (n--)
     {
       double alpha;
@@ -265,7 +295,91 @@ premultiplied_to_non_premultiplied (int    src_bands,
 
       BABL_PLANAR_STEP
     }
-  return n;
+  return samples;
+}
+
+
+
+static long
+rgba2rgba_gamma_2_2_premultiplied (void *src,
+                                   void *dst,
+                                   long  samples)
+{
+  long n=samples; 
+  while (n--)
+    {
+      double alpha = ((double*)src)[3];
+      ((double*)dst)[0] = linear_to_gamma_2_2 (((double*) src)[0]) * alpha;
+      ((double*)dst)[1] = linear_to_gamma_2_2 (((double*) src)[1]) * alpha;
+      ((double*)dst)[2] = linear_to_gamma_2_2 (((double*) src)[2]) * alpha;
+      ((double*)dst)[3] = alpha;
+      src+=4 * sizeof (double);
+      dst+=4 * sizeof (double);
+    }
+  return samples;
+}
+
+
+static long
+rgba_gamma_2_2_premultiplied2rgba (void *src,
+                                   void *dst,
+                                   long   samples)
+{
+  long n=samples; 
+  while (n--)
+    {
+      double alpha = ((double*) src)[3];
+      ((double*)dst)[0] = gamma_2_2_to_linear (((double*) src)[0] / alpha);
+      ((double*)dst)[1] = gamma_2_2_to_linear (((double*) src)[1] / alpha);
+      ((double*)dst)[2] = gamma_2_2_to_linear (((double*) src)[2] / alpha);
+      ((double*)dst)[3] = alpha;
+
+      src+=4 * sizeof (double);
+      dst+=4 * sizeof (double);
+    }
+  return samples;
+}
+
+
+static long
+rgba2rgba_gamma_2_2 (void *src,
+                     void *dst,
+                     long  samples)
+{
+  long n=samples; 
+  while (n--)
+    {
+      double alpha = ((double*)src)[3];
+      ((double*)dst)[0] = linear_to_gamma_2_2 (((double*) src)[0]);
+      ((double*)dst)[1] = linear_to_gamma_2_2 (((double*) src)[1]);
+      ((double*)dst)[2] = linear_to_gamma_2_2 (((double*) src)[2]);
+      ((double*)dst)[3] = alpha;
+      src+=4 * sizeof (double);
+      dst+=4 * sizeof (double);
+    }
+  return samples;
+}
+
+
+static long
+rgba_gamma_2_22rgba (void *src,
+                     void *dst,
+                     long   samples)
+{
+  long n=samples;
+  
+  while (n--)
+    {
+      double alpha = ((double*) src)[3];
+      ((double*)dst)[0] = gamma_2_2_to_linear (((double*) src)[0]);
+      ((double*)dst)[1] = gamma_2_2_to_linear (((double*) src)[1]);
+      ((double*)dst)[2] = gamma_2_2_to_linear (((double*) src)[2]);
+      ((double*)dst)[3] = alpha;
+
+      src+=4 * sizeof (double);
+      dst+=4 * sizeof (double);
+    }
+  return samples;
 }
 
 static void
@@ -278,68 +392,77 @@ conversions (void)
     NULL
   );
 
+
   babl_conversion_new (
+    babl_model_id (BABL_RGB),
     babl_model_id (BABL_RGBA),
-    babl_model_id (BABL_RGB_GAMMA_2_2),
-    "planar",      g3_gamma_2_2,
+    "planar",      copy_strip_1,
     NULL
   );
 
   babl_conversion_new (
     babl_model_id (BABL_RGBA),
-    babl_model_id (BABL_RGBA_GAMMA_2_2),
-    "planar",      g3_gamma_2_2,
+    babl_model_id (BABL_RGB),
+    "planar",      copy_strip_1,
     NULL
   );
 
   babl_conversion_new (
-    babl_model_id (BABL_RGB_GAMMA_2_2),
     babl_model_id (BABL_RGBA),
-    "planar",      g3_inv_gamma_2_2,
+    babl_model_id (BABL_RGBA_PREMULTIPLIED),
+    "planar",      non_premultiplied_to_premultiplied,
     NULL
   );
 
   babl_conversion_new (
-    babl_model_id (BABL_RGBA_GAMMA_2_2),
+    babl_model_id (BABL_RGBA_PREMULTIPLIED),
     babl_model_id (BABL_RGBA),
-    "planar",      g3_inv_gamma_2_2,
+    "planar",      premultiplied_to_non_premultiplied,
     NULL
   );
 
   babl_conversion_new (
-    babl_model_id (BABL_RGB),
     babl_model_id (BABL_RGBA),
-    "planar",      copy_strip_1,
+    babl_model_id (BABL_RGB_GAMMA_2_2),
+    "planar",      g3_gamma_2_2,
     NULL
   );
-
   babl_conversion_new (
+    babl_model_id (BABL_RGB_GAMMA_2_2),
     babl_model_id (BABL_RGBA),
-    babl_model_id (BABL_RGB),
-    "planar",      copy_strip_1,
+    "planar",      g3_inv_gamma_2_2,
     NULL
   );
 
   babl_conversion_new (
     babl_model_id (BABL_RGBA),
-    babl_model_id (BABL_RGBA_PREMULTIPLIED),
-    "planar",      non_premultiplied_to_premultiplied,
-    NULL
-  );
+    babl_model_id (BABL_RGBA_GAMMA_2_2),
+    "linear", rgba2rgba_gamma_2_2,
+    NULL);
+  babl_conversion_new (
+    babl_model_id (BABL_RGBA_GAMMA_2_2),
+    babl_model_id (BABL_RGBA),
+    "linear", rgba_gamma_2_22rgba,
+    NULL);
 
   babl_conversion_new (
-    babl_model_id (BABL_RGBA_PREMULTIPLIED),
     babl_model_id (BABL_RGBA),
-    "planar",      premultiplied_to_non_premultiplied,
-    NULL
-  );
+    babl_model_id (BABL_RGBA_GAMMA_2_2_PREMULTIPLIED),
+    "linear", rgba2rgba_gamma_2_2_premultiplied,
+    NULL);
+  babl_conversion_new (
+    babl_model_id (BABL_RGBA_GAMMA_2_2_PREMULTIPLIED),
+    babl_model_id (BABL_RGBA),
+    "linear", rgba_gamma_2_2_premultiplied2rgba,
+    NULL);
+  
 }
 
 static void
 formats (void)
 {
     babl_format_new (
-    "name", "srgb",
+    //"name", "srgb",
     "id", BABL_SRGB,
     babl_model_id     (BABL_RGB_GAMMA_2_2),
     babl_type_id      (BABL_U8),
@@ -376,4 +499,16 @@ formats (void)
     babl_component_id (BABL_GREEN), 
     babl_component_id (BABL_BLUE),
     NULL);
+
+#ifdef XXXX
+  babl_format_new (
+    "id", BABL_RGB565,
+     babl_model_id (BABL_RGB),
+    babl_component_id (BABL_RED), 
+    babl_component_id (BABL_GREEN), 
+    babl_component_id (BABL_BLUE),
+
+  );
+#endif
 }
+
index 000f32d147acd9169f4826498b1006b71baf4ab9..b27c5d34955b2539100831355698eaf948ece590 100644 (file)
@@ -60,14 +60,14 @@ models (void)
 {
   babl_model_new (
     "id", BABL_YCBCR,
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    babl_component_id (BABL_LUMA),
     babl_component_id (BABL_CB),
     babl_component_id (BABL_CR),
     NULL);
 
   babl_model_new (
     "id", BABL_YCBCR_ALPHA,
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    babl_component_id (BABL_LUMA),
     babl_component_id (BABL_CB),
     babl_component_id (BABL_CR),
     babl_component_id (BABL_ALPHA),
@@ -244,7 +244,7 @@ formats (void)
     babl_model_id  (BABL_YCBCR),
     babl_type_id   (BABL_U8_LUMA),
     babl_sampling  (1, 1),
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    babl_component_id (BABL_LUMA),
     babl_type_id   (BABL_U8_CHROMA),
     babl_sampling  (2, 2),
     babl_component_id (BABL_CB), 
@@ -260,7 +260,7 @@ formats (void)
     babl_model_id  (BABL_YCBCR),
     babl_type_id   (BABL_U8_LUMA),
     babl_sampling  (1, 1),
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    babl_component_id (BABL_LUMA),
     babl_type_id   (BABL_U8_CHROMA),
     babl_sampling  (2, 2),
     babl_component_id (BABL_CB), 
@@ -276,7 +276,7 @@ formats (void)
     babl_model_id  (BABL_YCBCR),
     babl_type_id   (BABL_U8_LUMA),
     babl_sampling  (1, 1),
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    babl_component_id (BABL_LUMA),
     babl_type_id   (BABL_U8_CHROMA),
     babl_sampling  (2, 1),
     babl_component_id (BABL_CB), 
@@ -291,7 +291,7 @@ formats (void)
     babl_model_id  (BABL_YCBCR),
     babl_type_id   (BABL_U8_LUMA),
     babl_sampling  (1, 1),
-    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
+    babl_component_id (BABL_LUMA),
     babl_type_id   (BABL_U8_CHROMA),
     babl_sampling  (4, 1),
     babl_component_id (BABL_CB), 
index 0f243afad3d2e1fd5c0aafca1e70b6882d92658c..d0ec866814a80a8fde968995d0e458bf467e7795 100644 (file)
         </ul>
 
         <h3>Shortcut coverage</h3>
-        <p>The diagram shown below is the coverage of shortcut conversions that already exist,
-           prior to the BablFishPath actually being operational, due to lack of testing of loss
-           against the reference conversions this is the most optimistic estimate. (<a href='BablFishPath.html'>Interactive version</a>)
+        <p>The diagram shown below is the coverage of shortcut conversions that already exist, only chains of converions that produce the same results as the reference conversions would result in are shown.
         </p>
 <pre style='font-size:50%;height:30em;overflow:scroll'>
 <!--BablFishPath-->
index 070d4cca0220339233f8c773f6c35e8951e885d6..b5dc30d929d5c9a69962a86ffe3bdad0f5fbeef9 100644 (file)
@@ -49,7 +49,7 @@
  *       gamma correction  (not really,. gamma correction belongs in seperate ops,.
  */
 
-#define USE_TABLES
+//#define USE_TABLES
 #ifdef USE_TABLES
 
 /* lookup tables used in conversion */
@@ -147,7 +147,6 @@ gggl_float_to_index16 (float f)
   return u.s[1];
 }
 
-
 static INLINE long
 conv_F_8 (unsigned char *src, unsigned char *dst, long samples)
 {
@@ -218,19 +217,13 @@ conv_F_8 (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      float     f = ((*(float *) src));
-      if (f < 0.0)
-        {
-          *(unsigned char *) dst = 0;
-        }
-      else if (f > 1.0)
-        {
-          *(unsigned char *) dst = 255;
-        }
-      else
-        {
-          *(unsigned char *) dst = rint (f * 255.0);
-        }
+      float f  = ((*(float *) src));
+      int   uval = rint (f * 255.0);
+
+      if (uval < 0) uval = 0;
+      if (uval > 255) uval = 255;
+      *(unsigned char *) dst = uval;
+
       dst += 1;
       src += 4;
     }
@@ -268,7 +261,7 @@ conv_8_F (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      (*(float *) dst) = (*(unsigned char *) src / 255.0);
+      (*(float *) dst) = ((*(unsigned char *) src) / 255.0);
       dst += 4;
       src += 1;
     }
@@ -291,6 +284,33 @@ conv_16_F (unsigned char *src, unsigned char *dst, long samples)
 
 #endif
 
+
+static INLINE long
+conv_F_D (unsigned char *src, unsigned char *dst, long samples)
+{
+  long n=samples;
+  while (n--)
+    {
+      *(double *) dst = ((*(float *) src));
+      dst += 8;
+      src += 4;
+    }
+  return samples;
+}
+
+static INLINE long
+conv_D_F (unsigned char *src, unsigned char *dst, long samples)
+{
+  long n=samples;
+  while (n--)
+    {
+      *(float *) dst = ((*(double *) src));
+      dst += 4;
+      src += 8;
+    }
+  return samples;
+}
+
 static INLINE long
 conv_16_8 (unsigned char *src, unsigned char *dst, long samples)
 {
@@ -373,28 +393,39 @@ conv_gaF_ga16 (unsigned char *src, unsigned char *dst, long samples)
 static INLINE long
 conv_rgba8_rgbaF (unsigned char *src, unsigned char *dst, long samples)
 {
-  conv_8_F (src, dst, samples * 4);
-  return samples;
+  return conv_8_F (src, dst, samples * 4) / 4;
 }
 
 static INLINE long
 conv_rgb8_rgbF (unsigned char *src, unsigned char *dst, long samples)
 {
-  conv_8_F (src, dst, samples * 3);
-  return samples;
+  return conv_8_F (src, dst, samples * 3) / 3;
 }
 
 static INLINE long
 conv_ga8_gaF (unsigned char *src, unsigned char *dst, long samples)
 {
-  conv_8_F (src, dst, samples * 2);
-  return samples;
+  return conv_8_F (src, dst, samples * 2) / 2;
 }
 
 #define conv_rgbA8_rgbAF conv_rgba8_rgbaF
 #define conv_gA8_gAF     conv_ga8_gaF
 #define conv_g8_gF       conv_8_F
 
+static INLINE long
+conv_rgbaF_rgbaD (unsigned char *src, unsigned char *dst, long samples)
+{
+  conv_F_D (src, dst, samples * 4);
+  return samples;
+}
+
+static INLINE long
+conv_rgbaD_rgbaF (unsigned char *src, unsigned char *dst, long samples)
+{
+  conv_D_F (src, dst, samples * 4);
+  return samples;
+}
+
 static INLINE long
 conv_rgba16_rgbaF (unsigned char *src, unsigned char *dst, long samples)
 {
@@ -514,7 +545,7 @@ conv_rgbAF_rgbaF (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      float     alpha = (*(float *) (src + 4 * 3));
+      float     alpha = (((float *) src)[3]);
       int       c;
       if (alpha >= 1.0)
         {
@@ -556,7 +587,7 @@ conv_rgbaF_rgbAF (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      float     alpha = (*(float *) (src + 4 * 3));
+      float     alpha = (((float *) src)[3]);
       int       c;
 
       if (alpha >= 1.0)
@@ -601,13 +632,13 @@ conv_rgbaF_rgbF (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      *(int *) dst = (*(int *) src);
+      *(float *) dst = (*(float *) src);
       dst += 4;
       src += 4;
-      *(int *) dst = (*(int *) src);
+      *(float *) dst = (*(float *) src);
       dst += 4;
       src += 4;
-      *(int *) dst = (*(int *) src);
+      *(float *) dst = (*(float *) src);
       dst += 4;
       src += 4;
       src += 4;
@@ -621,15 +652,15 @@ conv_rgbF_rgbaF (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      *(int *) dst = (*(int *) src);
-      dst += 4;
+      *(float *) dst = (*(float *) src);
       src += 4;
-      *(int *) dst = (*(int *) src);
       dst += 4;
+      *(float *) dst = (*(float *) src);
       src += 4;
-      *(int *) dst = (*(int *) src);
       dst += 4;
+      *(float *) dst = (*(float *) src);
       src += 4;
+      dst += 4;
       *(float *) dst = 1.0;
       dst += 4;
     }
@@ -739,15 +770,15 @@ conv_rgbaF_gaF (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      int       c;
-      float     sum = 0;
+      float     gray = 0;
 
-      for (c = 0; c < 3; c++)
-        {
-          sum += (*(float *) src);
-          src += 4;
-        }
-      (*(float *) dst) = sum / 3;
+      gray += (*(float *) src) * 0.212671;
+      src += 4;
+      gray += (*(float *) src) * 0.715160;
+      src += 4;
+      gray += (*(float *) src) * 0.072169;
+      src += 4;
+      (*(float *) dst) = gray;
       dst += 4;
       (*(int *) dst) = (*(int *) src);
       dst += 4;
@@ -838,7 +869,7 @@ conv_rgbaF_rgb8 (unsigned char *src, unsigned char *dst, long samples)
 
       for (c = 0; c < 3; c++)
         {
-          *(unsigned char *) dst = (*(float *) src) * 255.0;
+          *(unsigned char *) dst = rint ((*(float *) src) * 255.0);
           dst += 1;
           src += 4;
         }
@@ -914,7 +945,7 @@ conv_rgbA16_rgbaF (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      float     alpha = (*(unsigned short *) src + (3)) / 65535.0;
+      float     alpha = (((unsigned short *) src)[3]) / 65535.0;
       int       c;
 
       for (c = 0; c < 3; c++)
@@ -1242,15 +1273,16 @@ conv_rgb8_rgba8 (unsigned char *src, unsigned char *dst, long samples)
   long n=samples; 
   while (n--)
     {
-      *(unsigned int *) dst = *(unsigned int *) src;
+      /**(unsigned int *) dst = *(unsigned int *) src;
+      dst[3] = 255;*/
+
+      dst[0] = src[0];
+      dst[1] = src[1];
+      dst[2] = src[2];
       dst[3] = 255;
       src += 3;
       dst += 4;
     }
-  dst[0] = src[0];
-  dst[1] = src[1];
-  dst[2] = src[2];
-  dst[3] = 255;
   return samples;
 }
 
@@ -1311,7 +1343,36 @@ conv_rgba8_rgb8 (unsigned char *src, unsigned char *dst, long samples)
   return samples;
 }
 
-#define conv_rgbA8_rgb8 conv_rgbP8_rgb8
+static INLINE long
+conv_rgbA8_rgb8 (unsigned char *src, unsigned char *dst, long samples)
+{
+  long n=samples;
+  while (n--)
+    {
+      int alpha = src[3];
+      if (alpha == 255)
+        {
+          *dst++ = src[0];
+          *dst++ = src[1];
+          *dst++ = src[2];
+        }
+      else if (alpha == 0)
+        {
+          *dst++ = 0;
+          *dst++ = 0;
+          *dst++ = 0;
+        }
+      else
+        {
+          unsigned int aa = (255 << 16) / alpha;
+          *dst++ = (src[0] * aa) >> 16;
+          *dst++ = (src[1] * aa) >> 16;
+          *dst++ = (src[2] * aa) >> 16;
+        }
+      src += 4;
+    }
+  return samples;
+}
 
 #ifndef byteclamp
 #define byteclamp(j) do{if(j<0)j=0; else if(j>255)j=255;}while(0)
@@ -1689,125 +1750,133 @@ typedef struct Conversion
 int
 init (void)
 {
+  Babl *rgbaD = babl_format_new (
+      babl_model ("R'G'B'A"),
+      babl_type  ("double"),
+      babl_component ("R'"),
+      babl_component ("G'"),
+      babl_component ("B'"),
+      babl_component ("A"),
+      NULL);
   Babl *rgbaF = babl_format_new (
-      babl_model ("RGBA"),
+      babl_model ("R'G'B'A"),
       babl_type  ("float"),
-      babl_component ("R"),
-      babl_component ("G"),
-      babl_component ("B"),
+      babl_component ("R'"),
+      babl_component ("G'"),
+      babl_component ("B'"),
       babl_component ("A"),
       NULL);
   Babl *rgba16 = babl_format_new (
-      babl_model ("RGBA"),
+      babl_model ("R'G'B'A"),
       babl_type  ("u16"),
-      babl_component ("R"),
-      babl_component ("G"),
-      babl_component ("B"),
+      babl_component ("R'"),
+      babl_component ("G'"),
+      babl_component ("B'"),
       babl_component ("A"),
       NULL);
   Babl *rgba8 = babl_format_new (
-      babl_model ("RGBA"),
+      babl_model ("R'G'B'A"),
       babl_type  ("u8"),
-      babl_component ("R"),
-      babl_component ("G"),
-      babl_component ("B"),
+      babl_component ("R'"),
+      babl_component ("G'"),
+      babl_component ("B'"),
       babl_component ("A"),
       NULL);
   Babl *rgbAF = babl_format_new (
-      babl_model ("RaGaBaA"),
+      babl_model ("R'aG'aB'aA"),
       babl_type  ("float"),
-      babl_component ("Ra"),
-      babl_component ("Ga"),
-      babl_component ("Ba"),
+      babl_component ("R'a"),
+      babl_component ("G'a"),
+      babl_component ("B'a"),
       babl_component ("A"),
       NULL);
   Babl *rgbA16 = babl_format_new (
-      babl_model ("RaGaBaA"),
+      babl_model ("R'aG'aB'aA"),
       babl_type  ("u16"),
-      babl_component ("Ra"),
-      babl_component ("Ga"),
-      babl_component ("Ba"),
+      babl_component ("R'a"),
+      babl_component ("G'a"),
+      babl_component ("B'a"),
       babl_component ("A"),
       NULL);
   Babl *rgbA8 = babl_format_new (
-      babl_model ("RaGaBaA"),
+      babl_model ("R'aG'aB'aA"),
       babl_type  ("u8"),
-      babl_component ("Ra"),
-      babl_component ("Ga"),
-      babl_component ("Ba"),
+      babl_component ("R'a"),
+      babl_component ("G'a"),
+      babl_component ("B'a"),
       babl_component ("A"),
       NULL);
   Babl *rgbF = babl_format_new (
-      babl_model ("RGB"),
+      babl_model ("R'G'B'"),
       babl_type  ("float"),
-      babl_component ("R"),
-      babl_component ("G"),
-      babl_component ("B"),
+      babl_component ("R'"),
+      babl_component ("G'"),
+      babl_component ("B'"),
       NULL);
   Babl *rgb16 = babl_format_new (
-      babl_model ("RGB"),
+      babl_model ("R'G'B'"),
       babl_type  ("u16"),
-      babl_component ("R"),
-      babl_component ("G"),
-      babl_component ("B"),
+      babl_component ("R'"),
+      babl_component ("G'"),
+      babl_component ("B'"),
       NULL);
   Babl *rgb8 = babl_format_new (
-      babl_model ("RGB"),
+      babl_model ("R'G'B'"),
       babl_type  ("u8"),
-      babl_component ("R"),
-      babl_component ("G"),
-      babl_component ("B"),
+      babl_component ("R'"),
+      babl_component ("G'"),
+      babl_component ("B'"),
       NULL);
   Babl *gaF = babl_format_new (
-      babl_model ("YA"),
+      babl_model ("Y'A"),
       babl_type  ("float"),
-      babl_component ("Y"),
+      babl_component ("Y'"),
       babl_component ("A"),
       NULL);
   Babl *gAF = babl_format_new (
-      babl_model ("YaA"),
+      babl_model ("Y'aA"),
       babl_type  ("float"),
-      babl_component ("Ya"),
+      babl_component ("Y'a"),
       babl_component ("A"),
       NULL);
   Babl *gF = babl_format_new (
-      babl_model ("Y"),
+      babl_model ("Y'"),
       babl_type  ("float"),
-      babl_component ("Y"),
+      babl_component ("Y'"),
       NULL);
   Babl *ga16 = babl_format_new (
-      babl_model ("YA"),
+      babl_model ("Y'A"),
       babl_type  ("u16"),
-      babl_component ("Y"),
+      babl_component ("Y'"),
       babl_component ("A"),
       NULL);
   Babl *gA16 = babl_format_new (
-      babl_model ("YaA"),
+      babl_model ("Y'aA"),
       babl_type  ("u16"),
-      babl_component ("Ya"),
+      babl_component ("Y'a"),
       babl_component ("A"),
       NULL);
   Babl *g16 = babl_format_new (
-      babl_model ("Y"),
+      babl_model ("Y'"),
       babl_type  ("u16"),
-      babl_component ("Y"),
+      babl_component ("Y'"),
       NULL);
   Babl *ga8 = babl_format_new (
-      babl_model ("YA"),
+      babl_model ("Y'A"),
       babl_type  ("u8"),
-      babl_component ("Y"),
+      babl_component ("Y'"),
       babl_component ("A"),
       NULL);
   Babl *gA8 = babl_format_new (
-      babl_model ("YaA"),
+      babl_model ("Y'aA"),
       babl_type  ("u8"),
-      babl_component ("Ya"),
+      babl_component ("Y'a"),
       babl_component ("A"),
       NULL);
   Babl *g8 = babl_format_new (
-      babl_model ("Y"),
+      babl_model ("Y'"),
       babl_type  ("u8"),
-      babl_component ("Y"),
+      babl_component ("Y'"),
       NULL);
   Babl *yuv8 = babl_format_new (
       "name", "Y'CbCr u8",
@@ -1937,6 +2006,8 @@ init (void)
   o (rgbF, yuvF);
   o (yuvaF, rgbaF);
   o (rgbaF, yuvaF);
+  o (rgbaF, rgbaD);
+  o (rgbaD, rgbaF);
 #if 0
   o (rgbF, xyzF);
   o (xyzF, rgbF);